#coding=utf-8
#!/usr/bin/python

'''
Created on 2012-11-17

@author: Neo.Chen
'''

import os
import sys
import time
import socket
import signal
import traceback
import sys
import sqlite3

# 常用数据类型转换方式
# bytes object   b = b"example \xa6\xc7"
# str object   s = "example"
# str---------bytes
# str to bytes   bytes(s, encoding = "utf8")
# bytes to str   str(b, encoding = "utf-8")
# an alternative method
# str to bytes   str.encode(s)
# bytes to str   bytes.decode(b)
#还有个方法
# str to bytes   your_str.encode()
# bytes to str   your_bytes.decode()
# int---------bytes
# int to bytes  your_int.to_bytes(4, byteorder='big')
# bytes to int  int.from_bytes(b, byteorder='big')


#判断是否py3
def IsPy3():
    if sys.version_info.major == 3:
        return True
    else:
        return False

#从vcs同名函数移植
def _ForkMySelf_linux(pszExeName, seconds = 3):
    #从母体环境脱离
    #os.chdir("/")
    os.umask(0)
    os.setsid()
	# redirect standard file descriptors
    sys.stdout.flush()
    sys.stderr.flush()
    si = open(os.devnull, 'r')
    so = open(os.devnull, 'a+')
    se = open(os.devnull, 'a+')
    os.dup2(si.fileno(), sys.stdin.fileno())
    os.dup2(so.fileno(), sys.stdout.fileno())
    os.dup2(se.fileno(), sys.stderr.fileno())
    #start
    print("_ForkMySelf_linux enter, pid:%d" % (os.getpid()))
    signal.signal(signal.SIGPIPE, signal.SIG_IGN)
    signal.signal(signal.SIGCHLD, signal.SIG_IGN)   #交给系统init去回收
    while True:
        try:
            pid = os.fork()
        except OSError as e:
            sys.stderr.write("fork error! (%d) %s" % (e.errno, e.strerror))
            sys.exit(1)
        print("pid:%d" % (pid))

        if pid < -1:
            sys.stderr.write("create child process error!")
            sys.exit(1)
        elif pid > 0:
            '''
            try:
                if os.waitpid(pid, 0)[0] < 0:
                    sys.exit(1)
            except OSError as e:
                sys.stderr.write("waitpid error! (%d) %s" % (e.errno, e.strerror))
                sys.exit(1)
            print("sub proc exit.")
            '''
            try:
                os.waitpid(pid, 0)
            except OSError as e:
                sys.stderr.write("waitpid error! (%d) %s" % (e.errno, e.strerror))
            #print("sub proc exit.")
            time.sleep(seconds)
        else:
            break
    #print("_ForkMySelf_linux exit, pid:%d" % (os.getpid()))


#从vcs同名函数移植
def ForkMySelf(pszExeName, seconds = 3):
    if sys.platform != 'win32':
        _ForkMySelf_linux(pszExeName, seconds)

#自定义的编码函数
def encrypt(key, s):
    b = bytearray(str(s).encode("gbk"))
    n = len(b) # 求出 b 的字节数
    c = bytearray(n*2)
    j = 0
    for i in range(0, n):
        b1 = b[i]
        b2 = b1 ^ key # b1 = b2^ key
        c1 = b2 % 16
        c2 = b2 // 16 # b2 = c2*16 + c1
        c1 = c1 + 65
        c2 = c2 + 65 # c1,c2都是0~15之间的数,加上65就变成了A-P 的字符的编码
        c[j] = c1
        c[j+1] = c2
        j = j+2
    return c.decode("gbk")

#自定义的解码函数
def decrypt(key, s):
    c = bytearray(str(s).encode("gbk"))
    n = len(c) # 计算 b 的字节数
    if n % 2 != 0 :
        return ""
    n = n // 2
    b = bytearray(n)
    j = 0
    for i in range(0, n):
        c1 = c[j]
        c2 = c[j+1]
        j = j+2
        c1 = c1 - 65
        c2 = c2 - 65
        b2 = c2*16 + c1
        b1 = b2^ key
        b[i]= b1
    try:
        return b.decode("gbk")
    except:
        return "failed"


#调用开发服务上的接口发邮件
def send_email(strFrom, strTo, strSubject, strMessage):
    sock = socket.socket()
    try:
        sock.connect(("t238.sky-mobi.com", 6699))
    except:
        sock.close()
        print('email server closed.')
        return
    str = "%s|%s|%s|%s\0" % (strFrom, strTo, strSubject, strMessage)
    sock.send(str.encode())
    sock.close()

#py3的打开文件函数
def _open_file_for_py3(filepath, attrib):
    return open(filepath, attrib)

#py2的打开文件函数
def _open_file_for_py2(filepath, attrib):
    return file(filepath, attrib)

#通用的打开文件函数
def open_file(filepath, attrib):
    if IsPy3():
        log_file = _open_file_for_py3(filepath, attrib)
    else:
        log_file = _open_file_for_py2(filepath, attrib)
    return log_file

#追加的方式写日志
def append_log(filename, str):
    strNow = time.asctime()
    log_file = open_file(filename, "a")
    log_file.write("%s %s \r\n" % (strNow, str))
    log_file.close()

#写崩溃日志
def write_crash_log():
    info = sys.exc_info()
    etype = info[0]
    evalue = info[1]
    etb = traceback.extract_tb(info[2])
    stack = traceback.format_exc()
    strNow = time.asctime()
    print(strNow)
    print(info)
    print(stack)
    #写单独的日志文件
    str = 'Error in routine: your routine here\n '
    str += 'Error Type: ' + str(etype) + '\n '
    str += 'Error Value: ' + str(evalue) + '\n '
    str += 'Traceback: ' + str(etb) + '\n '
    str += stack
    append_log("./crash_py.log", str)

def create_sqlite_table(conn, table_name, sql):
    try:
        cn = conn.cursor()
        query_sql = "select count(*) from sqlite_master where type='table' and name='%s'" % (table_name)
        cn.execute(query_sql)
        res = cn.fetchall()
        print(res)                  #是一个二维列表 [(1,)]
        for line in res:
            print(line)             #得到一维列表 (1,)
            existTable = line[0]    #表是否已经存在
            print(existTable)

        if existTable != 1:
            cn.execute(sql)
            conn.commit()
        cn.close()
    except:
        print("create_sqlite_table error")

##################################################################################

def test_send_mail():
    send_email("admin@sky-mobi.com", "neo.chen@sky-mobi.com", "recserver restart", "rt")


def test_encrypt():
    key = 15
    s1 = encrypt(key, 'hello world')
    s2 = decrypt(key, s1)
    print(s1,'\n',s2)

def test_fork():
    ForkMySelf("fork test", 3)
    while True:
        time.sleep(10)
        print("main sleep")


def main():
    print("main start...")

if __name__ == '__main__':
    main()



















